/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "SnapshotCommon.h"
#include "log/Log.h"
#include "PluginUtilities.h"
#include "PluginConstants.h"

using namespace std;
using namespace Module;

namespace {
    const auto MODULE = "SnapshotCommon";
    const std::string NAS_VENDOR_TYPE_CYBERENGINE_FUSIONSTOR = "CyberEnginePacific";
}

SnapshotCommon::~SnapshotCommon()
{
    Module::CleanMemoryPwd(m_deviceInfo.password);
}
    
int SnapshotCommon::InitDeviceInfo()
{
    HCP_Log(INFO, MODULE) << "Enter InitDeviceInfo" << HCPENDLOG;
    ControlDeviceInfo localDeviceInfo;

    if (FillDeviceInfo(localDeviceInfo) != SUCCESS) {
        return FAILED;
    }

    if (GetVendorType(m_nasHost.vendorSubType) == Module::STORAGE_ENUM::DORADO) {
        m_localDeviceController = std::make_shared<DoradoNas>(localDeviceInfo, m_deviceInfo.fileSystemId, false);
    }
    if (GetVendorType(m_nasHost.vendorSubType) == Module::STORAGE_ENUM::FUSIONSTORAGE) {
        m_localDeviceController = std::make_shared<FusionStorageNas>(localDeviceInfo, m_deviceInfo.fileSystemId);
    }
    if (m_localDeviceController == nullptr) {
        HCP_Log(ERR, MODULE) << "Genrate m_localDeviceController failed" << HCPENDLOG;
        return FAILED;
    }

    HCP_Log(INFO, MODULE) << "Genrate m_localDeviceController successfully" << HCPENDLOG;
    return SUCCESS;
}

int SnapshotCommon::FillDeviceInfo(ControlDeviceInfo &localDeviceInfo)
{
    localDeviceInfo.userName = m_deviceInfo.username;
    localDeviceInfo.password = m_deviceInfo.password;
    localDeviceInfo.deviceName = m_deviceInfo.fileSystemName;
    std::string deploy_type = PluginUtils::GetDeployType();
    if (deploy_type == ANTI_RANSOMWARE_DEPLOY_TYPE) {
        INFOLOG("Fill device info for anti ransomware machine");
        localDeviceInfo.url = INNER_SAFE_IP;
        localDeviceInfo.port = INNER_SAFE_PORT;
    } else if (deploy_type == SECURITY_MACHINE_DEPLOY_TYPE) {
        INFOLOG("Fill device info for anti ransomware machine");
        localDeviceInfo.url = m_deviceInfo.ipList;
        localDeviceInfo.port = m_deviceInfo.port;
    }

    HCP_Log(INFO, MODULE) << "localDeviceInfo.userName: " << localDeviceInfo.userName << HCPENDLOG;
    HCP_Log(INFO, MODULE) << "localDeviceInfo.port: " << localDeviceInfo.port << HCPENDLOG;
    return SUCCESS;
}

Module::STORAGE_ENUM SnapshotCommon::GetVendorType(const std::string& inputVendorStr) const
{
    HCP_Log(INFO, MODULE) << "Get input vendor type: " << inputVendorStr << HCPENDLOG;

    if (inputVendorStr == NAS_VENDOR_TYPE_STR_HUAWEI_DORADO) {
        return Module::STORAGE_ENUM::DORADO;
    } else if (inputVendorStr == NAS_VENDOR_TYPE_STR_HUAWEI_FUSIONSTOR
        || inputVendorStr == NAS_VENDOR_TYPE_CYBERENGINE_FUSIONSTOR) {
        return Module::STORAGE_ENUM::FUSIONSTORAGE;
    }
    HCP_Log(WARN, MODULE) << "Unknown vendor type, set default type dorado" << HCPENDLOG;
    return Module::STORAGE_ENUM::DORADO;
}

void SnapshotCommon::ReportJobDetails(const std::string& label,
    const JobLogLevel::type &level, const SubJobStatus::type sts, int progress)
{
    SubJobDetails subJobDetails;
    std::vector<LogDetail> logDetailList;
    ActionResult result;
    LogDetail logDetail {};

    HCP_Log(INFO, MODULE) << "report job details jobId: " << m_jobId << " subjobid: " << m_subjobId <<
       " label: " << label << " level: " << level << " jobstatus: " << sts << " progress: " << progress << HCPENDLOG;
    AddLogDetail(logDetail, label, level);
    REPORT_LOG2AGENT(subJobDetails, result, logDetailList, logDetail, progress, 0, sts);
}

std::string SnapshotCommon::FormatSnapshotName(const std::string& snapshotName)
{
    HCP_Log(INFO, MODULE) << "Enter format snapshot name, origin snapshot name is " << snapshotName << HCPENDLOG;
    // pacific快照命名只能由数字、字母、下划线组成并且需以字母开头
    if (GetVendorType(m_nasHost.vendorSubType) == Module::STORAGE_ENUM::FUSIONSTORAGE) {
        std::string newSnapshotName = "pacific_";
        for (const char& c : snapshotName) {
            if (std::isalnum(c)) {
                newSnapshotName.push_back(c);
            }
        }
        return newSnapshotName;
    } else {
        return snapshotName;
    }
}